﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace robotGUI
{
    /* Settings window
     * This is a simple form containing a PropertyGrid displaying 
     * the current Settings object and a status display mechanism.
     */
 
    public partial class frmSettings : Form
    {
        robotSettings Settings;
        robotSettings.StatusEventHandler statusEvent;
        PropertyChangedEventHandler propertyEvent;

        const int MaxQueue = 30;
        public frmSettings(robotSettings Settings)
        {
            InitializeComponent();
            this.Settings = Settings;
            statusEvent = new robotSettings.StatusEventHandler(Settings_StatusEvent);
            propertyEvent = new PropertyChangedEventHandler(Settings_PropertyChanged);
            progressBar1.Maximum = MaxQueue;
            progressBar1.Style = ProgressBarStyle.Marquee;
            if (Settings.Invalid) lblStatus.Text = "Settings not valid!";
            else if (Settings.Current) lblStatus.Text = "Ready.";
            else if (Settings.IncomingCount == 0) lblStatus.Text = "Read Complete.";
            else progressBar1.Visible = true;
            setName();
        }

        void Settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            propertyGrid1.SelectedObject = Settings;
        }

        void setName()
        {
            string name = "Settings";
            if (Settings.Invalid) name += " (Invalid)";
            if (Settings.Current) name += " (Complete)";
            this.Text = name;
        }

        private void frmSettings_Load(object sender, EventArgs e)
        {
            //Bring in the Settings object
            propertyGrid1.SelectedObject = Settings;
            //Register the status listener
            Settings.StatusEvent += statusEvent;
            //Watch properties for changes
            Settings.PropertyChanged += propertyEvent;
        }

        //Got new status event
        void Settings_StatusEvent(object sender, robotSettings.StatusEventArgs e)
        {
            setName();
            Status(e.Message, e.Type);
        }

        //Present status
        void Status(string Message, statusType status)
        {
            lblStatus.Text = Message;
            if (status == statusType.Received)
            {
                int val = MaxQueue - (Settings.IncomingCount - 1);
                val = val > MaxQueue ? MaxQueue : val;
                val = val < 0 ? 0 : val;
                progressBar1.Style = ProgressBarStyle.Continuous;
                progressBar1.SetProgressNoAnimation(val);
                progressBar1.Visible = true;
                //Refresh propertyGrid contents
                //propertyGrid1.SelectedObject = Settings;
            }
            else
            {
                if (Settings.Current) lblStatus.Text = "Ready.";
                progressBar1.Value = 0;
                progressBar1.Visible = false;
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void frmSettings_FormClosing(object sender, FormClosingEventArgs e)
        {
            //Deregister status listener
            Settings.StatusEvent -= statusEvent;
            //Deregister change events
            Settings.PropertyChanged -= propertyEvent;
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            Settings.Invalidate();
            propertyGrid1.SelectedObject = Settings;
        }

        private void btnProfile_DropDownOpened(object sender, EventArgs e)
        {
            itemProfile1.Checked = (Settings.ACTIVE_PROFILE == profile.Profile_1);
            itemProfile2.Checked = (Settings.ACTIVE_PROFILE == profile.Profile_2);
        }

        private void itemProfile1_Click(object sender, EventArgs e)
        {
            itemProfile1.Image = Properties.Resources.car_tick;
            itemProfile2.Image = Properties.Resources.car;
            setProfile(Settings.ACTIVE_PROFILE = profile.Profile_1);
        }

        private void itemProfile2_Click(object sender, EventArgs e)
        {
            itemProfile1.Image = Properties.Resources.car;
            itemProfile2.Image = Properties.Resources.car_tick;
            setProfile(Settings.ACTIVE_PROFILE = profile.Profile_2);
        }

        private void setProfile(profile profile)
        {
            if (profile == profile.Profile_1) btnProfile.Text = "Profile 1";
            else btnProfile.Text = "Profile 2";
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Copying the active profile will overwrite the inactive profile.\r\nAll saved settings in the other profile will be lost!\r\nAre you sure you want to continue?", "Copy Profile", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
            {
               Settings.serialControl.sendValue(Command.COPY_PROFILE, robotMsg.DOOMSDAY_MAGIC);
               lblStatus.Text = "Profile copied.";
            }
        }


    }
    //http://stackoverflow.com/questions/5332616/disabling-net-progressbar-animation-when-changing-value
    public static class ExtensionMethods
    {
        /// <summary>
        /// Sets the progress bar value, without using Windows Aero animation
        /// </summary>
        public static void SetProgressNoAnimation(this ProgressBar pb, int value)
        {
            // To get around this animation, we need to move the progress bar backwards.
            if (value == pb.Maximum)
            {
                // Special case (can't set value > Maximum).
                pb.Value = value;           // Set the value
                pb.Value = value - 1;       // Move it backwards
            }
            else
            {
                pb.Value = value + 1;       // Move past
            }
            pb.Value = value;               // Move to correct value
        }
    }
}
